/* 
 * File:   AnimatedSprite.h
 * Copyright (C) 2008, 2009
 *		Sergio Padrino Recio (PadrinatoR)
 *		J. Daniel Expósito Polo (HellSpawn)
 *		Iván Villalba Sierra (Kasikiare)
 *
 * Created on 7 de septiembre de 2008, 19:25
 *
 * This file is part of BombProject.
 *
 * BombProject is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * BombProject is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with BombProject.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _ANIMATEDSPRITE_H
#define	_ANIMATEDSPRITE_H

#include "Sprite.h"
#include <string>
#include <map>
#include <vector>

using namespace std;

/**
 * Struct that stores information about an animation to be used in an AnimatedSprite.
 * @see AnimatedSprite
 */
typedef struct _Animation {
    string name;
    SDL_Surface *animation_surface;
    Sint16 frame_delay;
    Sint16 frame_width;
    Sint16 hotpoint_x, hotpoint_y;
    vector<int> frame_sequence;
} Animation;

/**
 * Represents a drawable <b>animated</b> sprite.
 * @see Sprite
 */
class AnimatedSprite : public Sprite {
public:

    /**
     * Animation flags: <br>
     * <b>ANIMATION_NORMAL</b>: Normal animation from first to last frame.<br>
     * <b>ANIMATION_REVERT</b>: Revert animation from last frame to first frame.<br>
     * <b>ANIMATION_PING_PONG</b>: Ping-pong animation from first frame to last frame and then to first frame again...<br>
     * <b>ANIMATION_N_TIMES</b>: The animation is played <b>N</b> times (that N is specified as an option).<br>
     * <b>ANIMATION_LOOP</b>: The animation is played forever.
     */
    enum AnimationFlags {
        //Animation type
        ANIMATION_NORMAL = 1,
        ANIMATION_REVERT = 2,
        ANIMATION_PING_PONG = 4,
        //Animation duration
        ANIMATION_N_TIMES = 8,
        ANIMATION_LOOP = 16
    };

    /**
     * Animation states:<br>
     * <b>ANIMATION_STOPPED</b>: The animation is not being played and it <b>cannot</b> be resumed.<br>
     * <b>ANIMATION_PLAYING</b>: The animation is being played.<br>
     * <b>ANIMATION_PAUSED</b>: The animation is not being played, but it can be <b>resumed</b>.<br>
     */
    enum AnimationStates {
        ANIMATION_STOPPED,
        ANIMATION_PLAYING,
        ANIMATION_PAUSED
    };

protected:
    Sint16 mCurrentFrame, mTimes;
    Sint16 mFrameCounter, mTimesCounter;
    AnimationFlags mFlags;
    AnimationStates mAnimationState;

    bool mFinished;
    bool mAnimationSet;
    Animation mCurrentAnimation;
    string mCurrentAnimationName;

    Sint8 mFrameSpeed;

    map<string, Animation> mAnimations;

public:
    AnimatedSprite();
    ~AnimatedSprite();

    void addAnimation(string animation_name, string animation_file, bool current = true);
    void removeAnimation(string animation_name);
    void removeAllAnimations();
    void setAnimation(string animation_name);
    //Playing animations
    void playAnimation(Uint16 flags = ANIMATION_NORMAL | ANIMATION_LOOP, Sint16 times = 1);
    void pauseAnimation();
    void stopAnimation();
    void resumeAnimation();
    void updateAnimation();
    bool hasFinished();
    void setFrame(int num_frame);

    void destroy();
};

#endif	/* _ANIMATEDSPRITE_H */

